home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 303_01 / heur.c < prev    next >
Text File  |  1990-05-14  |  13KB  |  638 lines

  1. /*
  2.  *    SCCS:    %W%    %G%    %U%
  3.  *    Attempt to guess things about the file.
  4.  *
  5.  *EMACS_MODES:c
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <a.out.h>
  10. #ifdef    COFF
  11. #include <ldfcn.h>
  12. #endif    /*  COFF  */
  13. #include "unc.h"
  14.  
  15. #define    INITDAT    256
  16. #define    INCDAT    128
  17.  
  18. #define    STRSCNT    3
  19. #define    STRECNT    3
  20.  
  21. char    *malloc(), *realloc();
  22.  
  23. void    gette(), getde(), setde(), putte(), putde();
  24. void    nomem();
  25. long    getdw();
  26. symbol    inventsymb();
  27.  
  28. long    endt;
  29. ef_fids    mainfile;
  30.  
  31. /*
  32.  *    Talk about implemented things.....
  33.  */
  34.  
  35. void    unimpl(msg)
  36. char    *msg;
  37. {
  38.     (void) fprintf(stderr, "Warning: handling of \"%s\" not implemented\n", msg);
  39. }
  40.  
  41. /*
  42.  *    Return 1 if string char, otherwise 0.
  43.  */
  44.  
  45. int    possstr(x)
  46. unsigned  x;
  47. {
  48.     if  (x >= ' '  &&  x <= '~')
  49.         return    1;
  50.     if  (x == '\n'  ||  x == '\t')
  51.         return    1;
  52.     return    0;
  53. }
  54.  
  55. /*
  56.  *    Guess things about data files.
  57.  */
  58.  
  59. void    intudat(fid)
  60. ef_fid  fid;
  61. {
  62.     register  int    i, j;
  63.     int    lt, input, invcnt;
  64.     long    offs, soffs, endd;
  65.     d_entry    fdat;
  66.     unsigned  char    *inbuf;
  67.     int    ibsize;
  68.     
  69.     inbuf = (unsigned  char *)malloc(INITDAT);
  70.     if  (inbuf == NULL)
  71.         nomem();
  72.     ibsize = INITDAT;
  73.     
  74.     offs = fid->ef_dbase;
  75.     endd = fid->ef_bbase;
  76.  
  77.     while  (offs < endd)  {
  78.         getde(fid, offs, &fdat);
  79.         if  (fdat.d_type != D_BYTE)  {
  80.             offs += fdat.d_lng;
  81.             continue;
  82.         }
  83.         
  84.         /*
  85.          *    Looks like general data.  Read in as much as possible.
  86.          */
  87.         
  88.         input = 0;
  89.         soffs = offs;
  90.         do  {
  91.             if  (input >= ibsize)  {
  92.                 ibsize += INCDAT;
  93.                 inbuf = (unsigned  char *)
  94.                     realloc((char *)inbuf, (unsigned)ibsize);
  95.                 if  (inbuf == NULL)
  96.                     nomem();
  97.             }
  98.             inbuf[input++] = fdat.d_contents;
  99.             offs++;
  100.             if  (offs >= endd)
  101.                 break;
  102.             getde(fid, offs, &fdat);
  103.         }  while  (fdat.d_type == D_BYTE && fdat.d_lab == NULL);
  104.         
  105.         /*
  106.          *    Now split up the data.
  107.          */
  108.         
  109.         for  (i = 0;  i < input;  )  {
  110.             
  111.             /*
  112.              *    Might be a string.
  113.              */
  114.             
  115.             if  (possstr(inbuf[i]))  {
  116.                 lt = input;
  117.                 if  (i + STRSCNT < lt)
  118.                     lt = i + STRSCNT;
  119.                 for  (j = i + 1;  j < lt;  j++)  {
  120.                     if  (inbuf[j] == '\0')
  121.                         break;
  122.                     if  (!possstr(inbuf[j]))
  123.                         goto  notstr;
  124.                 }
  125.                 
  126.                 /*
  127.                  *    Looks like a string then.
  128.                  */
  129.                 
  130.                 invcnt = 0;
  131.                 for  (j = i + 1; j < input;  j++)  {
  132.                     if  (inbuf[j] == '\0')  {
  133.                         j++;
  134.                         break;
  135.                     }
  136.                     if  (possstr(inbuf[j]))
  137.                         invcnt = 0;
  138.                     else  {
  139.                         invcnt++;
  140.                         if  (invcnt >= STRECNT)  {
  141.                             j -= invcnt - 1;
  142.                             break;
  143.                         }
  144.                     }
  145.                 }
  146.  
  147.                 setde(fid,
  148.                       soffs+i,
  149.                       (unsigned)(inbuf[j-1]=='\0'?D_ASCZ:D_ASC),
  150.                       j - i);
  151.                 for  (i++;  i < j;  i++)
  152.                     setde(fid, soffs+i, D_CONT, 1); 
  153.                 continue;
  154.             }
  155.  
  156. notstr:
  157.             /*
  158.              *    If on odd boundary, treat as a byte.
  159.              */
  160.             
  161.             if  ((soffs + i) & 1  ||  i + 1 >= input)  {
  162.                 setde(fid, soffs + i, D_BYTE, 1);
  163.                 i++;
  164.                 continue;
  165.             }
  166.  
  167.             /*
  168.              *    Treat as longs unless not enough.
  169.              */
  170.             
  171.             if  (i + 3 >= input)  {
  172.                 setde(fid, soffs + i, D_WORD, 2);
  173.                 setde(fid, soffs + i + 1, D_CONT, -1);
  174.                 i += 2;
  175.                 continue;
  176.             }
  177.  
  178.             /*
  179.              *    Treat as a long but mark changable.
  180.              */
  181.             
  182.             setde(fid, soffs + i, D_LONG, 4);
  183.             for  (j = 1;  j < 4;  j++)
  184.                 setde(fid, soffs + i + j, D_CONT, -j);
  185.             i += 4;
  186.         }
  187.     }
  188.     free((char *)inbuf);
  189.     
  190.     /*
  191.      *    Now zap bss segment.
  192.      */
  193.     
  194.     offs = fid->ef_bbase;
  195.     endd = fid->ef_end;
  196.  
  197.     while  (offs < endd)  {
  198.         getde(fid, offs, &fdat);
  199.         if  (fdat.d_type != D_BYTE)  {
  200.             offs += fdat.d_lng;
  201.             continue;
  202.         }
  203.  
  204.         soffs = offs;
  205.         do  {
  206.             offs++;
  207.             if  (offs >= endd)
  208.                 break;
  209.             getde(fid, offs, &fdat);
  210.         }  while  (fdat.d_type == D_BYTE && fdat.d_lab == NULL);
  211.         
  212.         setde(fid, soffs, D_BYTE, (int)(offs-soffs));
  213.         for  (i = -1, soffs++;  soffs < offs; i--, soffs++)
  214.             setde(fid, soffs, D_CONT, i); 
  215.     }
  216. }
  217.  
  218. /*
  219.  *    For non relocatable files, try to identify address pointers in
  220.  *    the data.
  221.  */
  222.  
  223. void    inturdat(fid)
  224. ef_fid    fid;
  225. {
  226.     register  long    offs = fid->ef_dbase;
  227.     register  int    i;
  228.     register  symbol  ds;
  229.     long  endd = fid->ef_bbase;
  230.     long  cont;
  231.     d_entry    dent, refdent;
  232.  
  233.     while  (offs < endd)  {
  234.         getde(fid, offs, &dent);
  235.         if  (dent.d_type != D_LONG)
  236.             goto  endit;
  237.         cont = getdw(fid, offs, R_LONG);
  238.         if  (cont < fid->ef_dbase || cont > fid->ef_end)
  239.             goto  endit;
  240.         getde(fid, cont, &refdent);
  241.         if  (refdent.d_type == D_CONT)  {
  242.             d_entry    pdent;
  243.             int    siz;
  244.             
  245.             if  (refdent.d_lng >= 0)
  246.                 goto  endit;
  247.             getde(fid, cont+refdent.d_lng, &pdent);
  248.             i = -refdent.d_lng;
  249.             refdent.d_lng += pdent.d_lng;
  250.             pdent.d_lng = i;
  251.             if  (pdent.d_type == D_LONG  &&  i == 2)
  252.                 siz = D_WORD;
  253.             else
  254.                 siz = D_BYTE;
  255.             refdent.d_type = siz;
  256.             pdent.d_type = siz;
  257.             putde(fid, cont - i, &pdent);
  258.             for  (i = 1;  i < refdent.d_lng;  i++)
  259.                 setde(fid, cont+i, D_CONT, -i);
  260.         }
  261.         if  ((ds = refdent.d_lab) == NULL)  {
  262.             if  (cont >= fid->ef_bbase)  {
  263.                 ds = inventsymb("BS");
  264. #ifdef    COFF
  265.                 ds->s_type = S_BSS;
  266. #else    /*  !COFF  */
  267.                 ds->s_type = BSS;
  268. #endif    /*  !COFF  */
  269.             }
  270.             else  {
  271.                 ds = inventsymb("DS");
  272. #ifdef    COFF
  273.                 ds->s_type = S_DATA;
  274. #else    /*  !COFF  */
  275.                 ds->s_type = DATA;
  276. #endif    /*  !COFF  */
  277.             }
  278.             ds->s_value = cont;
  279.             refdent.d_lab = ds;
  280.             putde(fid, cont, &refdent);
  281.         }
  282.         else
  283.             ds->s_used++;
  284.         dent.d_type = D_ADDR;
  285.         dent.d_relsymb = ds;
  286.         dent.d_rptr = ds->s_type;
  287.         putde(fid, offs, &dent);
  288.         for  (i = 1;  i < 4;  i++)
  289.             setde(fid, offs+i, D_CONT, 1);
  290. endit:
  291.         offs += dent.d_lng;
  292.     }
  293. }
  294.  
  295. /*
  296.  *    Recursively follow through the code, stopping at unconditional
  297.  *    branches and invalid instructions.
  298.  */
  299.  
  300. void    follseq(pos)
  301. long    pos;
  302. {
  303.     t_entry    tent;
  304.     int    lng;
  305.     long    npos;
  306.  
  307.     while  (pos < endt)  {
  308.         gette(&mainfile, pos, &tent);
  309.         if  (tent.t_amap)    /*  Been here  */
  310.             return;
  311.         tent.t_amap = 1;
  312.         lng = findinst(&tent, pos);
  313.         npos = pos + lng*2;
  314.         if  (npos > endt)  {
  315.             tent.t_vins = 0;
  316.             tent.t_lng = 1;
  317.             tent.t_type = T_UNKNOWN;
  318.             lng = 0;
  319.             npos = endt;
  320.         }
  321.         putte(&mainfile, pos, &tent);
  322.         pos = npos;
  323.         
  324.         if  (lng <= 0)
  325.             return;
  326.  
  327.         switch  (tent.t_bchtyp)  {
  328.         case  T_UNBR:
  329.             if  (tent.t_relsymb == NULL)
  330.                 return;
  331.             pos = tent.t_relsymb->s_value;
  332.             continue;
  333.         case  T_JSR:
  334.             if  (tent.t_relsymb != NULL)
  335.                 follseq(tent.t_relsymb->s_value);
  336.             continue;
  337.         case  T_CONDBR:
  338.             follseq(tent.t_relsymb->s_value);
  339.         default:
  340.             continue;
  341.         }
  342.     }
  343. }
  344.             
  345.             
  346. /*
  347.  *    Try to work out things about text files.
  348.  */
  349.  
  350. void    intutext()
  351. {
  352.     long    pos;
  353.     t_entry    tent;
  354.     int    lng;
  355.     
  356.     endt = mainfile.ef_tbase + mainfile.ef_tsize;
  357.     pos = mainfile.ef_entry;
  358. nextv:
  359.     for  (;  pos < endt;)  {
  360.         gette(&mainfile, pos, &tent);
  361.         if  (!tent.t_amap && tent.t_vins)  {
  362.             follseq(pos);
  363.             pos += 2;
  364.             goto  nextiv;
  365.         }
  366.         pos += tent.t_lng * 2;
  367.         if  (tent.t_bchtyp == T_UNBR)
  368.             goto  nextiv;
  369.     }
  370.     goto    dorest;
  371. nextiv:
  372.     for  (;  pos < endt;  pos += 2)  {
  373.         gette(&mainfile, pos, &tent);
  374.         if  (tent.t_bdest)
  375.             goto  nextv;
  376.     }
  377. dorest:
  378.     /*
  379.      *    Deal with unmapped instructions.
  380.      */
  381.     
  382. #ifdef    COFF
  383.      for  (pos = mainfile.ef_tbase;  pos < endt;)  {
  384. #else    /*  !COFF  */
  385.     for  (pos = 0;  pos < endt;)  {
  386.     for  (pos = mainfile.ef_entry;  pos < endt;)  {
  387. #endif    /*  !COFF  */
  388.         gette(&mainfile, pos, &tent);
  389.         switch  (tent.t_type)  {
  390.         case  T_BEGIN:
  391.             pos += tent.t_lng * 2;
  392.             continue;
  393.         case  T_UNKNOWN:
  394.             if  (tent.t_vins)  {
  395.                 lng = findinst(&tent, pos);
  396.                 putte(&mainfile, pos, &tent);
  397.                 if  (lng > 0)  {
  398.                     pos += lng * 2;
  399.                     continue;
  400.                 }
  401.             }
  402.         default:
  403.             pos += 2;
  404.             continue;
  405.         }
  406.     }
  407. }
  408.  
  409. /*
  410.  *    Invent local symbols.
  411.  */
  412.  
  413. void    intlsym()
  414. {
  415.     long    bpos, epos, hiref, hipos;
  416.     unsigned  llnum;
  417.     t_entry    tent;
  418.     register  symbol  tl;
  419.     
  420.     endt = mainfile.ef_tbase + mainfile.ef_tsize;
  421.     epos = mainfile.ef_entry;
  422.     for  (;;)  {
  423.         bpos = epos;
  424.         hiref = bpos;
  425.         if  (epos >= endt)
  426.             return;
  427.         gette(&mainfile, epos, &tent);
  428.         epos += tent.t_lng * 2;
  429.         for  (;  epos < endt;)  {
  430.             gette(&mainfile, epos, &tent);
  431.             if  (tent.t_gbdest